home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_10_03
/
cmenu.exe
/
CMENU3.C
< prev
next >
Wrap
Text File
|
1992-01-04
|
5KB
|
220 lines
/************************************************************
* Program: CMENU Menu Compiler
* Module: cmenu3.c
* Menu Compiler:
* Token Processing Functions
* Written by: Leor Zolman, 7/91
************************************************************/
#include "cmenu.h"
#include "ccmenu.h"
#if __STDC__
#pragma hdrstop
#endif
#include <ctype.h>
static int unget_flag = FALSE;
static int unget_token;
static char unget_tparam[MAX_CMD];
static int unget_vparam;
static int quoted_text;
#if __STDC__
char *getword(void);
int matchkey(char *);
#else
char *getword();
int matchkey();
#endif
/************************************************************
* ungettok():
* Push a token back into the input stream, to
* be returned by the following call to gettok().
* Only one level of push-back is supported; any attempt to
* push back a token when there is already one pushed back
* draws an "internal error" diagnostic.
************************************************************/
Void ungettok(tok)
int tok;
{
if (unget_flag) /* can't "unget" more than 1 item! */
fatalerr("internal error: ungettok() overflow");
unget_flag = TRUE;
unget_token = tok;
unget_vparam = vparam;
strcpy(unget_tparam, tparam);
return;
}
/************************************************************
* gettok():
* Read a token from the source input stream.
* If the token is a reserved word, the appropriate token
* value is returned.
* If the token is a string, the global "tparam" is set
* to the text of the string. White space within the
* string is only recognized if double quote ("...")
* characters are used to delimit the string.
* T_STRING is returned.
* If the token is a numeric value, the global "vparam"
* is set to the integer value specified, and
* T_VALUE is returned.
* Returns T_EOF on end-of-file.
************************************************************/
int gettok()
{
register c;
char nexttok[MAX_CMD];
char *wordp;
if (unget_flag) /* was a token "pushed back"? */
{ /* yes. set the pushed-back values and */
vparam = unget_vparam; /* attributes */
strcpy(tparam, unget_tparam); /* clear the */
unget_flag = FALSE; /* flag */
return unget_token; /* return pushed token */
}
*tparam = '\0'; /* clear parameter */
vparam = 0; /* value registers */
if (!*(wordp = getword())) /* get a token. */
return token = T_EOF; /* End of file */
if (quoted_text) /* string enclosed */
{ /* in quotes? */
strcpy(tparam, wordp);
return T_STRING;
}
if (!strcmp(wordp, ":")) /* colon is special */
return T_COLON; /* (non-alphabetic) */
if (c = matchkey(wordp)) /* reserved word? */
return c; /* yes, just return */
if (isdigit(*wordp)) /* handle numeric value */
{
vparam = atoi(wordp);
return T_VALUE;
}
else
{
strcpy(tparam, wordp);
return T_STRING;
}
}
/************************************************************
* getword():
* Read the next syntactic object from the input stream,
* and return a pointer to it.
* Return pointer to a null string on EOF.
* If object is a quoted string, drop the quotes and
* set the quoted_text flag (preserve whitespace).
* Otherwise strip all whitespace, commas and comments,
* return pointer to next word/number.
* Track current line number by incrementing lineno
* on each newline encountered.
************************************************************/
char *getword()
{
static char tok[MAX_CMD];
char quote_char;
register c,i;
quoted_text = FALSE;
*tok = '\0';
while ((c = getc(fp)) != EOF)
{
if (c == '\n') /* bump line number if */
lineno++; /* newline encountered */
if (isspace(c)) /* skip all whitespace */
continue;
if (c == ',' || c == ';') /* legal separators: ,; */
continue;
if (c == ':') /* special case: colon */
return ":";
if (c == '#') /* process comment */
{ /* wait for newline or EOF */
while(c = getc(fp))
{
if (c == EOF)
break;
if (c == '\n')
{
lineno++;
break;
}
}
continue; /* then get next token */
}
if (c == '"' || c == '\'') /* quoted string? */
{
quoted_text = TRUE;
quote_char = c;
for (i = 0; ;i++)
{
switch (c = getc(fp))
{
case '\n':
fatalerr("Unterminated string");
return NULL;
case EOF:
fatalerr("Unterminated string (line %d)",
lineno);
return NULL;
case '"':
case '\'':
if (c == quote_char)
{
tok[i] = '\0';
return tok;
}
default:
if (i == MAX_CMD)
{
tok[i - 1] = '\0';
fatalerr("String too long (max %d chars)",
MAX_CMD);
return NULL;
}
tok[i] = c;
}
}
}
tok[0] = c;
for (i = 1; (c = getc(fp)) != EOF; i++)
if (isspace(c) || c == ';' || c == ','
|| c == ':')
break;
else
tok[i] = tolower(c);
tok[i] = '\0';
ungetc(c, fp);
break;
}
return tok;
}